{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Clip GeoJSON with XYZ\n",
    "\n",
    "This example notebook loads a GeoJSON dataset, shows it on a map and lets you select a bounding box for which XYZ will send you the clipped GeoJSON."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from functools import partial\n",
    "\n",
    "import geojson\n",
    "import requests\n",
    "import warnings\n",
    "from ipywidgets import Textarea, VBox, Layout\n",
    "from ipyleaflet import Map, GeoJSON, \\\n",
    "    DrawControl, LayersControl, FullScreenControl, WidgetControl\n",
    "\n",
    "from xyzspaces.datasets import get_countries_data\n",
    "from xyzspaces.tools import subset_geojson\n",
    "from xyzspaces.utils import feature_to_bbox\n",
    "import xyzspaces"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-block alert-warning\">\n",
    "<b>Warning:</b> Before running below cells please make sure you have XYZ Token to interact with xyzspaces. \n",
    "                Please see README.md in notebooks folder for more info on XYZ_TOKEN\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Make a XYZ object\n",
    "try:\n",
    "    xyz_token = os.environ[\"XYZ_TOKEN\"]\n",
    "except KeyError:\n",
    "    xyz_token = \"MY-FANCY-XYZ-TOKEN\"\n",
    "    if xyz_token == \"MY-FANCY-XYZ-TOKEN\":\n",
    "        warnings.warn(\n",
    "            \"Please either set your actual token to env variable XYZ_TOKEN or \"\n",
    "            \"just assign value of your actual token to variable xyz_token above.\"\n",
    "        )\n",
    "xyz = xyzspaces.XYZ(credentials=xyz_token)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load GeoJSON dataset\n",
    "\n",
    "This loads a example GeoJSON dataset from `xyzspaces.datasets`, essentially this one with\n",
    "minor clean-ups: https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "gj_countries = get_countries_data()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create draw control\n",
    "\n",
    "Using the rectangle widget from the draw control you can select a bounding box defining a subset of the GeoJSON data to be shown in a text area."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "draw_control = DrawControl(position='topright') # position not working, yet\n",
    "draw_control.polygon = {}\n",
    "draw_control.polyline = {}\n",
    "draw_control.circle = {}\n",
    "draw_control.circlemarker = {}\n",
    "draw_control.rectangle = {\n",
    "    \"shapeOptions\": {\n",
    "        \"fillColor\": \"#fca45d\",\n",
    "        \"color\": \"#fca45d\",\n",
    "        \"fillOpacity\": 0.1\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Show simple map with example dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "height = 500\n",
    "m = Map(center=[0, 0], zoom=2, layout=Layout(width=\"100%\"))\n",
    "m.add_control(FullScreenControl(position='topright'))\n",
    "m.add_control(LayersControl(position='topright'))\n",
    "m.add_control(draw_control)\n",
    "m += GeoJSON(data=gj_countries, style={'color': 'blue'}, name=\"World Countries\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ui = VBox([m])\n",
    "ui"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Build/show extended map UI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def on_draw_callback(event, the_map=None, the_textarea=None):\n",
    "    \"\"\"Callback function for adding draw controls to a map.\n",
    "    \"\"\"\n",
    "    # TODO: make sure we react only to rectangles...\n",
    "    # print(event.type)\n",
    "    if event.name == \"last_draw\" and event.type == \"change\":\n",
    "        if the_textarea:\n",
    "            the_textarea.value = \"Clipping...\"\n",
    "        rect = event.new\n",
    "        bbox = feature_to_bbox(rect)\n",
    "        tiled_bbox = subset_geojson(xyz_token, gj_countries, bbox, clip=True)\n",
    "        if the_map:\n",
    "            style = dict(color=\"red\")\n",
    "            the_map.add_layer(GeoJSON(data=tiled_bbox, style=style, name=\"Foo\"))\n",
    "        if the_textarea:\n",
    "            the_textarea.value = geojson.dumps(tiled_bbox)\n",
    "        # draw_control.clear()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "gj_ta = Textarea(\"GeoJSON of the selected bounding box...\", layout=Layout(width=\"100%\", height=\"200px\"))\n",
    "draw_control.observe(partial(on_draw_callback, the_map=m, the_textarea=gj_ta))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ui.children = [m, gj_ta]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Select a bounding box on the map!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Click on the left rectangle button to select a bounding box on the shown dataset for which to create a clipped GeoJSON string in the right textarea! "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
